package com.skyworthclub.competition.controller;

import com.skyworthclub.competition.service.UserService;
import com.skyworthclub.competition.utils.web.CheckUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author li
 * @version 1.0
 * @since 18-10-17 下午4:52
 * 文件上传控制器
 **/
@Controller
@RequestMapping("/api/file/")
public class FileController {

    /**
     * 服务器地址
     */
    private static final String SERVER_ADDRESS = "https://scut.coocaa.club";

    /**
     * 头像存放目录
     */
    private static final String AVATAR_DIR = "/var/www/competition/static/upload/images/avatar/";
    /**
     * 比赛图片存放目录
     */
    private static final String MATCH_IMAGE_DIR = "/var/www/competition/static/upload/images/match/";
    /**
     * 头像访问路径
     */
    private static final String AVATAR_URL_PREFIX = "/static/upload/images/avatar/";
    /**
     * 比赛宣传图片访问路径
     */
    private static final String MATCH_IMAGE_URL_PREFIX = "/static/upload/images/match/";

    /**
     * 比赛详情图片存放目录
     */
    private static final String MATCH_DETAIL_IMAGE_DIR = "/var/www/competition/static/upload/images/match/detail/";
    /**
     * 比赛详情图片访问路径
     */
    private static final String MATCH_DETAIL_IMAGE_URL_PREFIX = "/static/upload/images/match/detail/";

    private final UserService userService;

    @Autowired
    public FileController(UserService userService) {
        this.userService = userService;
    }

    /**
     * 用户上传头像
     *
     * @param username      用户名
     * @param multipartFile 头像图片
     * @return 图片保存地址
     */
    @PreAuthorize("principal.username == username")
    @PostMapping("/user/setAvatar/{username}")
    public ResponseEntity<Map<String, Object>> setAvatar(@PathVariable String username,
                                                         @RequestParam("avatarImage") MultipartFile multipartFile) {

        Map<String, Object> map = new HashMap<>(4);
        long size = multipartFile.getSize();
        //检查文件大小
        if (size > MAX_FILE_SIZE) {
            map.put("status", "400");
            map.put("message", "文件大小不可以超过" + MAX_FILE_SIZE / (1024 * 1024) + "M！");
            return new ResponseEntity<>(map, HttpStatus.OK);
        }

        //检查文件格式
        boolean checkImage = CheckUtil.checkImage(multipartFile.getContentType());
        if (!checkImage) {
            map.put("status", "400");
            map.put("message", "文件格式不正确！");
            return new ResponseEntity<>(map, HttpStatus.OK);
        }

        //获取文件名
        String filename = multipartFile.getOriginalFilename();
        //获取文件后缀名
        assert filename != null;
        String suffix = filename.substring(filename.lastIndexOf("."));
        //构造文件名
        filename = username + "_avatar" + suffix;
        //获取上传文件路径
        File file = new File(AVATAR_DIR);
        if (!file.isDirectory() && !file.isFile()) {
            boolean mkdirs = file.mkdirs();
            if (mkdirs) {
                file = new File(AVATAR_DIR, filename);
            } else {
                throw new RuntimeException("创建头像文件目录失败");
            }
        } else {
            file = new File(AVATAR_DIR, filename);
        }

        //保存到服务器
        try {

            multipartFile.transferTo(file);
            String avatarUrl = SERVER_ADDRESS + AVATAR_URL_PREFIX + filename;

            //更新用户头像图片url
            boolean b = userService.updateAvatarUrl(username, avatarUrl);
            if (b) {
                map.put("status", 200);
                map.put("message", "上传成功！");
                map.put("avatarUrl", avatarUrl);
            } else {
                map.put("status", 500);
                map.put("message", "上传失败！");
            }

        } catch (IOException e) {
            e.printStackTrace();
            //打印日志

            map.put("status", 500);
            map.put("message", "上传失败！");
        }
        return new ResponseEntity<>(map, HttpStatus.OK);
    }

    /**
     * 上传比赛宣传图片
     *
     * @param multipartFile 图片文件
     * @return 图片文件地址
     */
    @PostMapping("/match/setImage")
    public ResponseEntity<Map<String, Object>> setMatchImage(
            @RequestParam("matchImage") MultipartFile multipartFile) {

        Map<String, Object> map = new HashMap<>(4);
        long size = multipartFile.getSize();
        //检查文件大小
        if (size > MAX_FILE_SIZE) {
            map.put("status", "400");
            map.put("message", "文件大小不可以超过" + MAX_FILE_SIZE / (1024 * 1024) + "M！");
            return new ResponseEntity<>(map, HttpStatus.OK);
        }

        //检查文件格式
        boolean checkImage = CheckUtil.checkImage(multipartFile.getContentType());
        if (!checkImage) {
            map.put("status", "400");
            map.put("message", "文件格式不正确！");
            return new ResponseEntity<>(map, HttpStatus.OK);
        }

        //获取文件名
        String filename = multipartFile.getOriginalFilename();
        //获取文件后缀名
        assert filename != null;
        String suffix = filename.substring(filename.lastIndexOf("."));
        //构造文件名
        filename = "match" + "_" + System.currentTimeMillis() + "_" + (int) (new Random().nextDouble() * 1000) + suffix;
        //获取上传文件路径
        File file = new File(MATCH_IMAGE_DIR);
        if (!file.isDirectory() && !file.isFile()) {
            boolean mkdirs = file.mkdirs();
            if (mkdirs) {
                file = new File(MATCH_IMAGE_DIR, filename);
            } else {
                throw new RuntimeException("创建比赛图片文件目录失败");
            }
        } else {
            file = new File(MATCH_IMAGE_DIR, filename);
        }

        //保存到服务器
        try {
            multipartFile.transferTo(file);
            String matchImageUrl = SERVER_ADDRESS + MATCH_IMAGE_URL_PREFIX + filename;

            map.put("status", 200);
            map.put("message", "上传成功！");
            map.put("matchImageUrl", matchImageUrl);

        } catch (IOException e) {
            e.printStackTrace();
            //打印日志
            map.put("status", 500);
            map.put("message", "上传失败！");
        }
        return new ResponseEntity<>(map, HttpStatus.OK);

    }


    /** 富文本编辑器上传图片
     * @param multipartFile 图片文件
     */
    @PostMapping("/match/imageUpload")
    public ResponseEntity<Map<String, Object>> uploadImage(@RequestParam("image") MultipartFile multipartFile) {

        Map<String, Object> map = new HashMap<>(4);
        long size = multipartFile.getSize();
        //检查文件大小
        if (size > MAX_FILE_SIZE) {
            map.put("status", "400");
            map.put("message", "文件大小不可以超过" + MAX_FILE_SIZE / (1024 * 1024) + "M！");
            return new ResponseEntity<>(map, HttpStatus.OK);
        }

        //检查文件格式
        boolean checkImage = CheckUtil.checkImage(multipartFile.getContentType());
        if (!checkImage) {
            map.put("status", "400");
            map.put("message", "文件格式不正确！");
            return new ResponseEntity<>(map, HttpStatus.OK);
        }
        //构造文件名
        String filename = multipartFile.getOriginalFilename();
        //获取文件后缀名
        assert filename != null;
        String suffix = filename.substring(filename.lastIndexOf("."));
        //构造文件名
        filename = "image" + "_" + System.currentTimeMillis() + "_" + (int) (new Random().nextDouble() * 1000) + suffix;
        //获取上传文件路径
        LocalDate date = LocalDate.now();
        String dateDir = date.getYear() + "/" + date.getMonth() + "/" + date.getDayOfMonth() + "/";
        String path = MATCH_DETAIL_IMAGE_DIR + dateDir;
        File file = new File(path);
        if (!file.isDirectory() && !file.isFile()) {
            boolean mkdirs = file.mkdirs();
            if (mkdirs) {
                file = new File(path, filename);
            } else {
                throw new RuntimeException("创建图片文件目录失败！");
            }
        } else {
            file = new File(path, filename);
        }

        try {
            multipartFile.transferTo(file);
            String imageUrl = SERVER_ADDRESS +  MATCH_DETAIL_IMAGE_URL_PREFIX + dateDir + filename;

            //构建返回体
            map.put("status", 200);
            map.put("message", "上传成功");
            map.put("imageUrl", imageUrl);
            return new ResponseEntity<>(map, HttpStatus.OK);

        } catch (IOException e) {
            e.printStackTrace();
            map.put("status", 500);
            map.put("message", "上传失败");
            return new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }

    private static final int MAX_FILE_SIZE = 1024 * 1024 * 10;

}

